﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProgNetComponents.Collections;
using System.Windows.Forms;
using ProgNetComponents.Data.SqlCe;
using System.Data;
using ProgNetComponents.Ini;
using ProgNetComponents.Interfaces;
using System.Collections;

namespace ProgNetComponentsDx.Shortcut
{
    public static class ShortcutCache
    {
        public static event EventHandler<ShortcutEventArgs> ShortcutChanged;
        private static void OnShortCutChanged(object ShortcutId, Keys keys)
        {
            if (ShortcutChanged != null)
            {
                ShortcutChanged(null, new ShortcutEventArgs(ShortcutId, keys));
            }
        }
        public static ShortcutGrabber Grabber
        {
            get;
            set;
        } 

        private static NamedObjectCollection _RegisteredItems = new NamedObjectCollection();
        public static NamedObjectCollection RegisteredItems
        {
            get { return _RegisteredItems; }
        }
        private static NamedObjectCollection _SavedItems = new NamedObjectCollection();
        public static NamedObjectCollection SavedItems
        {
            get { return _SavedItems; }
        }


        public static bool IsTheSameId(object id1, object id2)
        {
            return GetKey(id1) == GetKey(id2);
        }
        public static string GetKey(object id)
        {
            string key = "";
            if (id != null && id.GetType().IsEnum)
            {
                key = id.GetType().FullName;
                key = key.Replace("+", ".").XReplace("_Group\\.", ".") + ".";
            }
            key += id.AsString();
            return key;
        }

        public static void RegisterGroups(IList groups, Type NamesType)
        {
            string key = NamesType.FullName + ".";
            foreach (INamedGroup g in groups)
            {
                RegisterGroups(g, key + g.Name);
            }
        }
        private static void RegisterGroups(INamedGroup group, string key)
        {
            RegisterItems(group.Items, key);
            foreach (INamedGroup g in group.Groups)
            {
                RegisterGroups(g, key + "." + g.Name);
            }
        }
        private static void RegisterItems(IList items, string key)
        {
            foreach (INamedObject o in items)
                RegisteredItems.Add(key + "." + o.Name, o);
        }

        public static Shortcut GetItem(object itemId)
        {
            string name = GetKey(itemId);
            if (RegisteredItems.Contains(name))
                return RegisteredItems[name].Value as Shortcut;
            return null;
        }
        public static Keys GetShortkutKeys(object itemId)
        {
            Shortcut o = GetItem(itemId);
            Keys value = Keys.None;
            if (o != null)
            {
                string key = GetKey(itemId);
                if (SavedItems.Contains(key))
                    value = SavedItems[key].Value.AsEnum<Keys>(Keys.None);
                else
                {
                    value = o.DefaultShortcut;
                }
            }
            else if(itemId is string)
            {
                string key = GetKey(itemId);
                if (SavedItems.Contains(key))
                    value = SavedItems[key].Value.AsEnum<Keys>(Keys.None);
            }
            return value;
        }

        public static void GetShortcuts()
        {
            if (Grabber != null)
                _SavedItems =  Grabber.ReadItems();
        }

        public static bool SaveShortcuts()
        {
            bool res= true;
            return res;
        }

        public static void SetShortcut(object shortCutId, Keys value, bool save = false)
        {
            Grabber.SetItemValue(shortCutId, value, save);
            string key = GetKey(shortCutId);
            if (SavedItems.Contains(key))
            {
                SavedItems[key].Value = value;
            }
            else
            {
                SavedItems.Add(key, value);
            }
            if (save)
            {
                Grabber.SaveSingleItem(shortCutId);

                OnShortCutChanged(shortCutId, value);
            }
        }

        public static bool IsShortcutSaved(object shortCutId)
        {
            string key = GetKey(shortCutId);
            return SavedItems.Contains(key);
        }
    }

    public class ShortcutEventArgs : EventArgs
    {
        private object _ShortcutId;
        private Keys _Keys;

        public ShortcutEventArgs(object shortCutId, Keys keys)
        {
            _ShortcutId = shortCutId;
            _Keys = keys;
        }
        public object ShortcutId
        {
            get { return _ShortcutId; }
        }
        public Keys Keys
        {
            get { return _Keys; }
        }
    }

    public abstract class ShortcutGrabber
    {
        protected abstract NamedObjectCollection _ReadItems();
        protected abstract bool _SaveItems();
        protected abstract void _SaveSingleItem(object itemId);
        protected abstract void _SetItemValue(object itemId, Keys value, bool save = false);

        internal void SetItemValue(object optionId, Keys value, bool save = false)
        {
            _SetItemValue(optionId, value, save);
        }
        internal NamedObjectCollection ReadItems()
        {
            return _ReadItems();
        }
        internal bool SaveItems()
        {
            return _SaveItems();
        }
        internal void SaveSingleItem(object itemId)
        {
            _SaveSingleItem(itemId);
        }
    }

    public class SqlCeShortcutGrabber : ShortcutGrabber
    {
        private ProgNetComponents.Data.SqlCe.SqlCeDataManager _Manager = new ProgNetComponents.Data.SqlCe.SqlCeDataManager();
        public ProgNetComponents.Data.SqlCe.SqlCeDataManager Manager
        {
            get { return _Manager; }
        }
        
        private DataTable table = null;
        public DataTable Table
        {
            get
            {
                if (table == null)
                {
                    table = new DataTable(TableName);
                    table.Columns.Add(ShortcutNameColumn);
                    table.Columns.Add(ShortcutValueColumn,  typeof(int));
                    table.PrimaryKey = new DataColumn[] { table.Columns[ShortcutNameColumn] };
                }
                return table;
            }
        }

        public string TableName
        {
            get;
            set;
        }
        public string ShortcutNameColumn
        {
            get;
            set;
        }
        public string ShortcutValueColumn
        {
            get;
            set;
        }

        protected override NamedObjectCollection _ReadItems()
        {
            NamedObjectCollection n = new NamedObjectCollection();
            
            if (Manager.TableDefsCount == 0)
                Manager.AddTableDef(Table, "SELECT " + ShortcutNameColumn + "," + ShortcutValueColumn + " FROM " + TableName);

            Manager.FillTable(Table);
            Table.AcceptChanges();
            foreach (DataRow r in Table.Rows)
            {
                n.Add(r[ShortcutNameColumn].AsString(), r[ShortcutValueColumn].AsEnum<Keys>(Keys.None));
            }
            return n;
        }

        protected override bool _SaveItems()
        {
            return Manager.UpdateTable(Table);
        }

        protected override void _SaveSingleItem(object itemId)
        {
            string name = ShortcutCache.GetKey(itemId);
            bool res = false;
            DataRow r = table.SelectFirstRow(ShortcutNameColumn + " = " + name.EscapeSql());
            if (r != null)
            {
                DataTable d = Table.Clone();
                d.ImportRow(r);
                res = Manager.UpdateTable(d);
                if (res)
                    r.AcceptChanges();
            }
        }

        protected override void _SetItemValue(object itemId, Keys value, bool save=false)
        {
            string name = ShortcutCache.GetKey(itemId);

            DataRow r = table.SelectFirstRow(ShortcutNameColumn + " = " + name.EscapeSql());
            if (r == null)
            {
                r = Table.NewRow();
                r[ShortcutNameColumn] = name;
                Table.Rows.Add(r);
            }
            r[ShortcutValueColumn] = (int)value;
            if (save)
                _SaveSingleItem(itemId);
        }
    }

    //public class IniShortcutGrabber : ShortcutGrabber
    //{
    //    private IniFile ini;
    //    private bool IsRegistered
    //    {
    //        get
    //        {
    //            return RegisteredShortcuts.Count > 0;
    //        }
    //    }

    //    public IniShortcutGrabber(string file)
    //    {
    //        ini = new IniFile(file);
    //    }
    //    protected override NamedObjectCollection _ReadShortcuts()
    //    {
    //        ini.ReadIni();
    //        NamedObjectCollection val = new NamedObjectCollection();
    //        string ShortcutName;
    //        string ShortcutGroup;
    //        int ShortcutValue;
    //        foreach (KeyValuePair<string, Dictionary<string,string>> kvp in ini.IniValues)
    //        {
    //            ShortcutGroup = kvp.Key;
    //            foreach (KeyValuePair<string, string> key in kvp.Value)
    //            {
    //                if (IsRegistered)
    //                    ShortcutName = "[" + ShortcutGroup + "] " + key.Key;
    //                else
    //                    ShortcutName = kvp.Key;
    //                ShortcutValue = key.Value.AsInt();
    //                val.Add(ShortcutName, ShortcutValue.AsEnum<Keys>(Keys.None));
    //            }
    //        }
    //        return val;
    //    }

    //    protected override bool _SaveShortcuts()
    //    {
    //        return ini.SaveIni();
    //    }

    //    protected override void _SetShortcut(string name, Keys value)
    //    {
    //        base._SetShortcut(name, value);
    //        string group = name.GetFirstMatch("\\[(.*)\\] (\\w*)");
    //        string _name = name.GetFirstMatch("\\[(.*)\\] (\\w*)", 2);
    //        if (!IsRegistered)
    //        {
    //            group = "SHORTCUTS";
    //            _name = name;
    //        }

    //        ini.WriteValueToCache(group, name, value.AsInt().AsString());
    //    }

    //    protected override bool _SaveShortcut(string name)
    //    {
    //        string group = name.GetFirstMatch("\\[(.*)\\] (\\w*)");
    //        string _name = name.GetFirstMatch("\\[(.*)\\] (\\w*)", 2);
    //        if (!IsRegistered)
    //        {
    //            group = "SHORTCUTS";
    //            _name = name;
    //        }
    //        int i = (int)GetShortcutKeys(name);
    //        return ini.WriteValueToFile(group, _name, i.AsString());
    //    }
    //}
}
